package com.laboratory.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.laboratory.exception.LabException;
import com.laboratory.mapper.UserMapper;
import com.laboratory.model.dto.user.UserUpdPwdDto;
import com.laboratory.model.dto.user.UserLoginDto;
import com.laboratory.model.entity.LoginLog;
import com.laboratory.model.entity.User;
import com.laboratory.model.dto.user.UserQueryDto;
import com.laboratory.service.LoginLogService;
import com.laboratory.service.UserService;
import com.laboratory.utils.HttpUtils;
import com.laboratory.utils.JwtUtils;
import com.laboratory.result.ResultCodeEnum;
import com.laboratory.utils.SecurityHolderUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 *
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    @Autowired
    private LoginLogService loginLogService;
    ;

    @Override
    public Map<String, Object> login(UserLoginDto userLoginDto) {
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();

        // 登录日志
        LoginLog loginLog = new LoginLog();
        loginLog.setUserName(userLoginDto.getName());
        loginLog.setLoginTime(new Date());
        //loginLog.setLoginIp(HttpUtil.getIpAddress());
        loginLog.setLoginIp(HttpUtils.getIpByNetwork());
        loginLog.setLoginAddr(HttpUtils.getIpPossessionByFile(loginLog.getLoginIp()));
        loginLog.setDriverName(HttpUtils.getBrowserNameAndVersion());
        loginLog.setOsName(System.getProperty("os.name"));
        loginLog.setLoginState(1);


        // 根据用户输入的用户名得到用户信息
        User u = baseMapper.selectOne(new QueryWrapper<User>().eq("user_name", userLoginDto.getName()));

        // 判断用户是否为空
        if (ObjectUtil.isNull(u)) {
            loginLog.setLoginState(0);
            loginLogService.save(loginLog);
            throw new LabException(ResultCodeEnum.USERNAME_NOT_FOUND);
        }

        // 判断用户输入的密码和当前查询的用户密码是否一致
        if (!u.getPassword().equals(DigestUtil.md5Hex(userLoginDto.getPwd()))) {
            loginLog.setLoginState(0);
            loginLogService.save(loginLog);
            throw new LabException(ResultCodeEnum.PASSWORD_ERROR);
        }

        loginLogService.save(loginLog);

        Map<String, String> claimMap = new HashMap<>();
        claimMap.put("userId", u.getId().toString());
        claimMap.put("userName", u.getUserName());
        claimMap.put("trueName", u.getTrueName());

        String token = JwtUtils.createToken(claimMap);

        // 返回登录信息
        HashMap<String, Object> map = new HashMap<>();
        map.put("token", token);

        return map;
    }

    @Override
    public PageInfo<User> getAll(Integer pIndex, Integer pSize, UserQueryDto userQueryDto) {
        // 开启分页
        PageHelper.startPage(pIndex, pSize);

        // 条件
        QueryWrapper<User> qw = new QueryWrapper<>();

        // 判断传过来的对象是否为空
        if (ObjectUtil.isNotEmpty(userQueryDto)) {
            // 判断账号是否为空
            if (!StrUtil.isEmpty(userQueryDto.getName())) {
                qw.like("user_name", userQueryDto.getName());
            }

            // 判断邮箱是否为空
            if (!StrUtil.isEmpty(userQueryDto.getEmail())) {
                qw.eq("user_email", userQueryDto.getEmail());
            }

            if (ObjectUtil.isNotEmpty(userQueryDto.getRoleId())) {
                qw.eq("role_id", userQueryDto.getRoleId());
            }

            if (StrUtil.isNotEmpty(userQueryDto.getSex())) {
                qw.eq("user_sex", userQueryDto.getSex());
            }
        }

        //根据id倒序
        qw.orderByDesc("id");

        return new PageInfo<>(baseMapper.selectList((qw)));
    }

    @Override
    public User getInfo(String token) {
        DecodedJWT decoded = JwtUtils.verifyToken(token);
        Claim userId = decoded.getClaims().get("userId");

        User user = baseMapper.selectById(userId.asString());

        if (ObjectUtil.isNull(user)) {
            throw new LabException(ResultCodeEnum.DATA_ERROR);
        }

        return user;
    }

    @Override
    public boolean save(User entity) {
        // 密码加密
        entity.setPassword(DigestUtil.md5Hex(entity.getPassword()));
        return super.save(entity);
    }

    @Override
    public Boolean updatePwd(UserUpdPwdDto userUpdPwdDto) {
        // 查询用户
        User user = baseMapper.selectById(SecurityHolderUtils.getUserId());

        // 判断旧密码是否正确
        if (!DigestUtil.md5Hex(userUpdPwdDto.getOldPwd()).equals(user.getPassword())) {
            throw new LabException("旧密码错误", 201);
        } else {
            // 修改密码
            user.setPassword(DigestUtil.md5Hex(userUpdPwdDto.getNewPwd()));
            return baseMapper.updateById(user) > 0;
        }
    }

}




